package com.ruoyi.fjtseac.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ruoyi.common.annotation.DataSource;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.core.redis.RedisCache;
import com.ruoyi.common.enums.DataSourceType;
import com.ruoyi.common.exception.ServiceException;
import com.ruoyi.common.utils.SecurityUtils;
import com.ruoyi.common.xss.Xss;
import com.ruoyi.fjtseac.domain.dto.UpdateVideoForm;
import com.ruoyi.fjtseac.domain.dto.VideoDto;
import com.ruoyi.fjtseac.domain.po.Audio;
import com.ruoyi.fjtseac.domain.vo.VideoVo;
import com.ruoyi.fjtseac.mapper.TypeMapper;
import com.ruoyi.fjtseac.mapper.VideoMapper;
import com.ruoyi.fjtseac.domain.po.Video;
import com.ruoyi.fjtseac.service.VideoService;
import com.ruoyi.fjtseac.util.*;
import com.ruoyi.fjtseac.util.aop.RedisCacheClear;
import com.ruoyi.fjtseac.util.aop.RedisCacheEnable;
import com.ruoyi.fjtseac.util.aop.TableEnum;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.multipart.MultipartFile;

import javax.validation.constraints.Min;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull;
import java.util.*;

import static com.ruoyi.common.utils.PageUtils.startPage;
import static com.ruoyi.fjtseac.util.Constants.FALSE;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author zzl
 * @since 2022-07-06
 */
@Service
@Validated
public class VideoServiceImpl extends ServiceImpl<VideoMapper, Video> implements VideoService {

    @Value("${path.video}")
    private String video;
    @Value("${cos.host}")
    private String host;
    private final FileUtil fileUtil;
    final LocalFile localFile;
    private final VideoMapper videoMapper;
    private final RedisCache redisCache;

    public VideoServiceImpl(FileUtil fileUtil, LocalFile localFile, VideoMapper videoMapper, RedisCache redisCache) {
        this.fileUtil = fileUtil;
        this.localFile = localFile;
        this.videoMapper = videoMapper;
        this.redisCache = redisCache;
    }

    @Override
    public AjaxResult upload(VideoDto videoDto, String uuid) {

        String time = localFile.getFileTime(videoDto.getVideoFile(), Constants.VIDEO);
        System.out.println(time);
        if (time == null) {
            return AjaxResult.error("获取视频时长失败");
        }
        //oss，视频先存临时文件夹后再进行转码
        String videoUrl = fileUtil.upload(videoDto.getVideoFile(), Constants.VIDEO, uuid);
        if (Objects.equals(videoUrl, FALSE)) {
            return AjaxResult.error("视频文件因某种原因上传失败，请重新上传");
        }
//        //oss转码前替换
//        String outputPath = videoUrl.replaceAll(videoTemp,videoPath);
        //oss视频转码
//        fileUtil.transcodeToH264(videoUrl, outputPath);
        Video video = DtoToPoMapper.INSTANCE.toVideo(videoDto);
        video.setVideoUrl(videoUrl);
        video.setDuration("time");
        int n = videoMapper.insert(video);
        if (n == 0) {
            fileUtil.delete(videoUrl, videoDto.getCoverUrl().replaceAll(host + "/", ""));
            return AjaxResult.error("数据插入失败");
        }
        return AjaxResult.success();
    }

    @Override
    public AjaxResult upload(MultipartFile file, String uuid) {
        String videoUrl = fileUtil.upload(file, Constants.VIDEO, uuid);
        if (Objects.equals(videoUrl, FALSE)) {
            return AjaxResult.error("视频文件因某种原因上传失败，请重新上传");
        }
        return AjaxResult.success("视频插入文章成功", videoUrl);
    }


    @Override
    public AjaxResult delete(Integer id) {
        Video video = videoMapper.selectById(id);
        if (video == null) {
            return AjaxResult.error("该视频不存在");
        }
        videoMapper.deleteById(id);
        System.out.println(fileUtil.delete(video.getVideoUrl().replaceAll(host + "/", ""), video.getCoverUrl().replaceAll(host + "/", "")));
        if (!fileUtil.delete(video.getVideoUrl().replaceAll(host + "/", ""), video.getCoverUrl().replaceAll(host + "/", ""))) {
            return AjaxResult.success("部分文件或全部文件删除文件失败，请登录服务器删除对应文件");
        }
        return AjaxResult.success();
    }

    @Override
    public AjaxResult update(UpdateVideoForm updateVideoForm) {
        Video oldVideo = videoMapper.selectById(updateVideoForm.getVideoId());
        if (oldVideo == null) {
            return AjaxResult.error("不存在该数据");
        }
        //更新数据库
        Video video = DtoToPoMapper.INSTANCE.toVideo(updateVideoForm);
        int i =  videoMapper.updateById(video);
        if (i == 0) {
            return AjaxResult.error("修改数据库视频记录失败");
        }
        fileUtil.delete(oldVideo.getCoverUrl().replaceAll(host + "/", ""));
        return AjaxResult.success();
    }

    @DataSource(value = DataSourceType.SLAVE)
    @Override
    public AjaxResult search(String param, int pageNum, int pageSize) {
        startPage(pageNum, pageSize);
        QueryWrapper<Video> wrapper = new QueryWrapper<>();
        wrapper.like(param != null, "video_title", param)
                .orderBy(true, false, "create_time");
        List<Video> videos = videoMapper.selectList(wrapper);
        System.out.println(videos);
        List<VideoVo> videoVoList = new ArrayList<>();
        for (Video video : videos) {
            //将浏览量先存入redis，进行数据预热。
            String key = TableEnum.VIDEO.getTableName() + ":" + video.getVideoId();
            if (redisCache.getCacheObject(key) == null){
                redisCache.setCacheObject(key, video.getPv());
            }
            VideoVo videoVo = PoToVoMapper.INSTANCE.toVideoVo(video);
            videoVoList.add(videoVo);
        }
        return AjaxResult.getPageResult(videos, videoVoList);
    }

    @Override
    public AjaxResult getProgress(String uuid) {
        return AjaxResult.success(fileUtil.getProgress(uuid));
    }


}
